package Assignment13_BooleanOrSignal;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Assignment13_BooleanOrSignal {

	public static void main(String[] args) {

		Assignment13_BooleanOrSignal m = new Assignment13_BooleanOrSignal();

		Scanner sc = new Scanner(System.in);

		String first_line = sc.nextLine();
		String second_line = sc.nextLine();

		System.out.println("first_line ::" + first_line);
		System.out.println("second_line ::" + second_line);

		// populating arrays of inputs
		Scanner sc1 = new Scanner(first_line);
		int numberofpairs1 = sc1.nextInt();

		System.out.println("numberofpairs1 :: " + numberofpairs1);

		int[] arr1 = new int[numberofpairs1 * 2];

		while (sc1.hasNextInt()) {

			for (int i = 0; i < arr1.length; i++) {

				arr1[i] = sc1.nextInt();

				// System.out.println("arr1 :: " + arr1[i]);

			}

		}

		Scanner sc2 = new Scanner(second_line);
		int numberofpairs2 = sc2.nextInt();

		System.out.println("numberofpairs2 :: " + numberofpairs2);
		int[] arr2 = new int[numberofpairs2 * 2];

		while (sc2.hasNextInt()) {

			for (int i = 0; i < arr2.length; i++) {

				arr2[i] = sc2.nextInt();

				// System.out.println("arr2 :: " + arr2[i]);

			}

		}

		populateArraylistOfObjects(arr1, arr2);

		sc.close();
		sc1.close();
		sc2.close();

	}

	private static void populateArraylistOfObjects(int[] arr1, int[] arr2) {

		// System.out.println("arr1.length :: " + arr1.length);
		// System.out.println("arr2.length :: " + arr2.length);

		ArrayList<Signal> al1 = new ArrayList<Signal>();
		ArrayList<Signal> al2 = new ArrayList<Signal>();

		for (int i = 0; i < arr1.length; i = i + 2) {

			Signal s = new Signal(arr1[i], arr1[i + 1]);

			al1.add(s);
		}

		for (int j = 0; j < arr2.length; j = j + 2) {

			Signal s = new Signal(arr2[j], arr2[j + 1]);

			al2.add(s);

		}
		generateSignal(al1, al2);

	}

	private static void generateSignal(ArrayList<Signal> al1,
			ArrayList<Signal> al2) {

		Set<Signal> hs_final = new HashSet<Signal>();
		// Set<Signal> hs_final2 = new HashSet<Signal>();

		for (int i = 0; i < al1.size(); i++) {

			for (int j = 0; j < al2.size(); j++) {

				if (((al2.get(j).x < al1.get(i).y)
						& (al1.get(i).y < al2.get(j).y) || (al2.get(j).x < al1
						.get(i).x) & (al1.get(i).x < al2.get(j).y))
						// second
						|| ((al1.get(i).x < al2.get(j).y)
								& (al2.get(j).y < al1.get(i).y) || (al1.get(i).x < al2
								.get(j).x) & (al2.get(j).x < al1.get(i).y))) {

					// keep this
					hs_final.add(new Signal(
							Math.min(al1.get(i).x, al2.get(j).x), Math.max(
									al1.get(i).y, al2.get(j).y)));

				} else {

					hs_final.add(new Signal(al1.get(i).x, al1.get(i).y));

				}

			}

		}// first for loop ends

		for (int j = 0; j < al2.size(); j++) {

			for (int i = 0; i < al1.size(); i++) {

				if (((al2.get(j).x < al1.get(i).y)
						& (al1.get(i).y < al2.get(j).y) || (al2.get(j).x < al1
						.get(i).x) & (al1.get(i).x < al2.get(j).y))
						// second
						|| ((al1.get(i).x < al2.get(j).y)
								& (al2.get(j).y < al1.get(i).y) || (al1.get(i).x < al2
								.get(j).x) & (al2.get(j).x < al1.get(i).y))) {

					// keep this
					hs_final.add(new Signal(
							Math.min(al1.get(i).x, al2.get(j).x), Math.max(
									al1.get(i).y, al2.get(j).y)));

				} else {

					// al_final.add(new Signal(min(al1.get(i).x, al2.get(j).x),
					// max(al1.get(i).y, al2.get(i).y)));

					hs_final.add(new Signal(al2.get(j).x, al2.get(j).y));

				}

			}

		}// second for loop ends

		System.out.println("hs_final(before) :: " + hs_final);
		// System.out.println("hs_final2(before) :: " + hs_final2);

		straightenList(new ArrayList<Signal>(hs_final)); // conversion of a
															// Hashset into an
															// Arraylist

	}

	private static void straightenList(ArrayList<Signal> al_final) { // works
																		// fine

		Collections.sort(al_final, new Comparator<Signal>() {

			@Override
			public int compare(Signal s1, Signal s2) {

				if (s1.x == s2.x) {
					return s2.y - s1.y;
				} else {

					return s1.x - s2.x;

				}

			}

		});

		System.out.println("al_final(after) :: " + al_final);

		modifyArray(al_final, al_final); // Will wrap the overlapping signals

	}

	private static void modifyArray(ArrayList<Signal> al1, ArrayList<Signal> al2) {

		HashSet<Signal> hs = new HashSet<Signal>();

		for (int i = 0; i < al1.size(); i++) {

			for (int j = 0; j < al2.size(); j++) {

				boolean stop_matching = false;
				try {

					if ((((al2.get(j).x <= al1.get(i).y)
							& (al1.get(i).y <= al2.get(j).y) || (al2.get(j).x <= al1
							.get(i).x) & (al1.get(i).x <= al2.get(j).y))
					// second
					|| ((al1.get(i).x <= al2.get(j).y)
							& (al2.get(j).y <= al1.get(i).y) || (al1.get(i).x <= al2
							.get(j).x) & (al2.get(j).x <= al1.get(i).y)))
							& stop_matching == false) {

						// keep this
						hs.add(new Signal(Math.min(al1.get(i).x, al2.get(j).x),
								Math.max(al1.get(i).y, al2.get(j).y)));
						stop_matching = true;
						if (stop_matching == true)
							break;

					}
				} catch (Exception e) {
				}
			}
		}

		ArrayList<Signal> al_end = new ArrayList<Signal>(hs);
		straightenList1(al_end);

	}

	private static void straightenList1(ArrayList<Signal> al_end) {

		Collections.sort(al_end, new Comparator<Signal>() {

			@Override
			public int compare(Signal s1, Signal s2) {

				return s1.x - s2.x;
			}

		});

		String final_format = al_end.toString().replace("[", "")
				.replace(",", "").replace("]", "");

		System.out.println(al_end.size() + " " + final_format);

	}
}